home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- ** $Revision: 1.2 $
- ** $Date: 1994/02/22 23:31:29 $
- */
- /*
- ** This program is to demonstrate the use of OpenGL with both X windows
- ** and pixmaps. One context is shared between a pixmap and a window.
- ** Note that since the default is to render to the pixmap, no image will
- ** be drawn in the window when it first comes up.
- **
- ** The picture consists of three triangles clipped and
- ** layered using depth and scissor tests.
- **
- ** The user controls rendering with three keys:
- ** w Render to the window
- ** p Render to the pixmap (default)
- ** c Copy the contents of the pixmap into the window
- **
- ** The program runs in rgb mode by default. To run in color index mode,
- ** use the command line option -c.
- */
-
- #include <GL/glx.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <X11/keysym.h>
-
- static int RGBattributes[] = {
- GLX_RGBA,
- GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- None,
- };
-
- static int CIattributes[] = {
- GLX_DEPTH_SIZE, 1,
- None,
- };
-
- int width = 200, height = 200;
-
- static void Reshape(int w, int h)
- {
- glViewport(0, 0, (GLint)w, (GLint)h);
-
- width = w;
- height = h;
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);
- glMatrixMode(GL_MODELVIEW);
- }
-
-
- static void Init(void)
- {
-
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glClearIndex(1.0);
-
- glClearDepth(1);
- glClearStencil(0);
- glEnable(GL_DEPTH_TEST);
- }
-
-
-
- static void DoDisplay(void)
- {
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
-
- glColor3ub(200, 0, 0);
- glIndexi(2);
- glBegin(GL_POLYGON);
- glVertex3i(-4, -3, -2);
- glVertex3i( 4, -3, -2);
- glVertex3i( 0, 4, -2);
- glEnd();
- glFlush();
-
- glEnable(GL_SCISSOR_TEST);
- glScissor(width/3, height/3, width/3, height/3);
- glColor3ub(0, 200, 0);
- glIndexi(29);
- glBegin(GL_POLYGON);
- glVertex3i(-4, -3, 0);
- glVertex3i( 4, -3, 0);
- glVertex3i( 0, 4, 0);
- glEnd();
- glDisable(GL_SCISSOR_TEST);
- glFlush();
-
- glColor3ub(0, 0, 200);
- glIndexi(31);
- glBegin(GL_POLYGON);
- glVertex3i(-4, -4, -1);
- glVertex3i( 4, -4, -1);
- glVertex3i( 0, 3, -1);
- glEnd();
- glFlush();
-
- }
-
-
- static void Usage(void)
- {
- printf("Usage: pixmap [-c]\n");
- printf(" -c: Run in color index mode\n");
- exit(-1);
- }
-
-
- static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
- {
- if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
- return GL_TRUE;
- }
- return GL_FALSE;
- }
-
- int main(int argc, char *argv[])
- {
- /* X variables */
- XVisualInfo *vi;
- Display *dpy;
- Colormap cmap;
- Window window;
- Window root;
- Pixmap pixmap;
- XSetWindowAttributes swa;
- XEvent event;
- GC gc;
-
- /* GLX variables */
- GLXContext cx;
- GLXPixmap pm;
-
- GLboolean needDisplay;
- int gx, gy, i;
- unsigned int gwidth, gheight, gborder_width, gdepth;
- Status xggStatus;
- int rgb = 1; /* Use rgb mode by default */
-
- /*
- ** Read command line arguments.
- */
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
- case 'c':
- rgb = 0;
- break;
- default:
- Usage();
- }
- } else {
- Usage();
- }
- }
-
-
- /*
- ** Open the X connection.
- */
- dpy = XOpenDisplay(0);
- if (!dpy) {
- fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
- return -1;
- }
-
- /*
- ** Select the X visual enabled for OpenGL, using RGB or CI mode.
- */
- vi = glXChooseVisual(dpy, DefaultScreen(dpy),
- rgb ? RGBattributes : CIattributes);
- if (!vi) {
- fprintf(stderr, "No singlebuffered rgba visual on \"%s\"\n",
- getenv("DISPLAY"));
- return -1;
- }
-
- /*
- ** Create a colormap.
- ** If its RGB, then the visual is TrueColor and the map is already
- ** allocated read-only. For CI, allocate the entire map.
- */
- cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
- rgb ? AllocNone: AllocAll);
- /* XXX
- ** could use some colormap setting here.
- */
-
- /*
- ** Set the window attributes in the XSetWindowAttributes structure.
- ** Ask for events at exposure, change in window structure, key
- ** presses.
- */
- swa.border_pixel = 0;
- swa.colormap = cmap;
- swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
- | KeyReleaseMask;
- window = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 10, 10,
- width, height,
- 0, vi->depth, InputOutput, vi->visual,
- CWBorderPixel|CWColormap|CWEventMask, &swa);
- XSetStandardProperties(dpy, window, "pixmap", "pixmap", None, argv, argc,
- NULL);
- XSetWMColormapWindows(dpy, window, &window, 1);
-
- /*
- ** Make the window visible by mapping it.
- */
- XMapWindow(dpy, window);
- XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
-
- /*
- ** Create an X graphics context.
- */
- gc = XCreateGC(dpy, window, 0, NULL);
-
- /*
- ** Create a pixmap, using the same depth as the window visual.
- ** Next, create a a GLX rendering area using that pixmap.
- */
- pixmap = XCreatePixmap(dpy, RootWindow(dpy, vi->screen),
- width, height, vi->depth);
- pm = glXCreateGLXPixmap(dpy, vi, pixmap);
- xggStatus = XGetGeometry(dpy, pixmap, &root, &gx, &gy, &gwidth, &gheight,
- &gborder_width, &gdepth);
-
- /*
- ** Create an OpenGL context, and make it current to the pixmap.
- */
- cx = glXCreateContext(dpy, vi, 0, GL_FALSE);
- if (!glXMakeCurrent(dpy, pm, cx)) {
- fprintf(stderr, "Can't make pixmap current to context\n");
- return -1;
- }
-
-
- printf("rendering to pixmap\n");
- Init();
-
- needDisplay = GL_TRUE;
-
- /*
- ** Main event loop
- */
- for (;;) {
- do {
- XNextEvent(dpy, &event);
- switch (event.type) {
- case Expose:
- needDisplay = GL_TRUE;
- break;
- case ConfigureNotify:
- width = event.xconfigure.width;
- height = event.xconfigure.height;
- Reshape(width, height);
- needDisplay = GL_TRUE;
- break;
- case KeyPress:
- {
- char buf[100];
- int rv;
- KeySym ks;
-
- rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
- switch (ks) {
-
- case XK_c:
- /*
- ** Copy pixmap into window.
- */
- xggStatus = XGetGeometry(dpy, window, &root, &gx, &gy,
- &gwidth, &gheight, &gborder_width, &gdepth);
- XCopyArea(dpy, pixmap, window, gc, 0, 0, gwidth,
- gheight, gx, gy);
- printf("copying the pixmap into the window\n");
- break;
-
- case XK_p:
- /*
- ** Make the pixmap the current rendering target.
- */
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- if (!glXMakeCurrent(dpy, pm, cx)) {
- fprintf(stderr,
- "Can't make pixmap current to context\n");
- return -1;
- }
- needDisplay = GL_TRUE;
- printf("rendering to pixmap\n");
- break;
-
- case XK_w:
- /*
- ** Make the window the current rendering target.
- */
- if (!glXMakeCurrent(dpy, window, cx)) {
- fprintf(stderr,
- "Can't make window current to context\n");
- return -1;
- }
- needDisplay = GL_TRUE;
- printf("rendering to window\n");
- break;
- case XK_Escape:
- return 0;
- }
- }
- break;
- }
- } while (XPending(dpy) != 0);
-
- if (needDisplay) {
- needDisplay = GL_FALSE;
- DoDisplay();
- glFlush();
- }
- }
- }
-